﻿
using LiuQiuRong.Chat.Repositories.Users;
using LiuQiuRong.Chat.Utilities.Crypto;
using LiuQiuRong.Chat.Utilities.Helper;
using LiuQiuRong.Chat.Utilities.Model;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using System;
using System.Collections.Generic;
using System.Security.Claims;
using System.Linq;
using LiuQiuRong.Chat.Businesses.Users.Dtos;
using AutoMapper;
using LiuQiuRong.Chat.Repositories.Users.Entities;

namespace LiuQiuRong.Chat.Businesses.Users
{
    public partial class UserServices : BaseService<UserEntity, UserDto>, IUserServices
    {
        private readonly IUserRepository _userRepository;
        private readonly IHttpContextAccessor _accessor;
        private readonly IDistributedCache _cache;
        public UserServices(IHttpContextAccessor accessor
            ,IDistributedCache cache
            ,IMapper mapper
            ,IUserRepository userRepository
            )
        {
            _userRepository = userRepository;
            _accessor = accessor;
            _cache = cache;
            _mapper = mapper;
        }

        public ServiceResult Add(UserUnsafeDto user)
        {
            ServiceResult ret = new ServiceResult();
            if (user == null)
                ret.SetData("n", "参数有误。");
            else
            {
                user.Password = Encryption.EncryptAES(Encryption.GetMD5HashFromString(user.Password), "1qaz@WSX");
                if (_userRepository.Insert(user) > 0)
                {
                    ret.SetData("y", "注册成功。");
                }
                else
                {
                    ret.SetData("n", "注册失败。");
                }
            }

            return ret;
        }

        public ServiceResult Login(UserUnsafeDto user)
        {
            ServiceResult ret = new ServiceResult();
            if (user == null)
                ret.SetData("n", "参数有误。");
            else
            {
                ret.SetData("n", "账号或者密码错误。");
                var result = _userRepository.GetByExpression(x => x.Phone == user.Phone);
                if (result != null)
                {
                    if (Encryption.EncryptAES(Encryption.GetMD5HashFromString(user.Password), "1qaz@WSX") == result.Password)
                    {

                        var loginUser = _mapper.Map<UserLoginDto>(result);
                        //{
                        //    UserId = result.UserId.ToString(),
                        //    Phone = result.Phone,
                        //    UserName = result.UserName,
                        //    LoginTime = DateTime.Now
                        //};

                        if (SessionExtensionsHelper.Get<UserLoginDto>(_accessor.HttpContext.Session, "user") == null)
                        {
                            SessionExtensionsHelper.Set(_accessor.HttpContext.Session, "user", loginUser);
                        }
                        var onlineUsers = DistributedCacheExtensionsHelper.GetValue<List<UserLoginDto>>(_cache, "User");
                        if (onlineUsers == null)
                        {
                            onlineUsers = new List<UserLoginDto>
                            {
                                loginUser
                            };
                            DistributedCacheExtensionsHelper.SetValue(_cache, "User", onlineUsers);
                        }
                        else
                        {
                            if (!onlineUsers.Any(x => x.Phone == loginUser.Phone))
                            {
                                onlineUsers.Add(loginUser);
                                _cache.Remove("User");
                                DistributedCacheExtensionsHelper.SetValue(_cache, "User", onlineUsers);
                            }
                        }

                        var claims = new List<Claim>
                        {
                            new Claim(ClaimTypes.Name,loginUser.Phone),
                            new Claim("LoginTime",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"))
                        };
                        var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
                        _accessor.HttpContext.SignInAsync(
                            CookieAuthenticationDefaults.AuthenticationScheme,
                            new ClaimsPrincipal(claimsIdentity),
                            new AuthenticationProperties { IsPersistent = false });

                        ret.SetData("y", "登录成功。", loginUser.UserName);
                    }
                }
            }
            return ret;
        }

        public UserLoginDto GetCurrentUser(ClaimsPrincipal claims)
        {
            var ret = SessionExtensionsHelper.Get<UserLoginDto>(_accessor.HttpContext.Session, "user");

            if (ret == null)
            {
                var result = _userRepository.GetByExpression(x => x.Phone == claims.Identity.Name);
                if (result != null)
                {
                    ret = _mapper.Map<UserLoginDto>(result);
                    //ret = new LoginUser
                    //{
                    //    LoginTime = DateTime.Parse(claims.FindFirst("LoginTime").Value),
                    //    Phone = result.Phone,
                    //    UserName = result.UserName,
                    //    UserId = result.UserId.ToString()
                    //};
                }
                else
                {
                    ret = new UserLoginDto();
                }
            }
            return ret;

        }

        public List<UserLoginDto> GetOnlineUsers()
        {
            return DistributedCacheExtensionsHelper.GetValue<List<UserLoginDto>>(_cache, "User"); ;
        }

        public ServiceResult CancelAuthorize()
        {
            var result = new ServiceResult();
            if (_accessor.HttpContext.User.Identity.IsAuthenticated)
            {
                _accessor.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                result.SetData("y", "退出成功");
            }
            return result;
        }
    }
}
